from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import login_required
from google.appengine.api import users
from google.appengine.ext.webapp import template
from google.appengine.ext import db
from model import *
from record import TableRecord
import os, StringIO, csv, datetime,logging
def clean_record(record):
    '''clean a record, process values'''
    for fld in Impact.fields().keys():
        v = record.get(fld)
        if fld in ['x', 'y']:
            try:
                v = float('%.6f' % float(record[fld]))
            except:
                v = -1
        elif fld in ['roadway', 'garage', 'adaparking', 'sidewalk']:
            if v=='TRUE':
                v = True
            else:
                v = False
        elif fld in ['start_date', 'end_date']:
            m, d, y = v.split('/')
            v = datetime.datetime(int(y), int(m), int(d))
        record[fld] = v
    return record

class ManageHandler(webapp.RequestHandler):
    """the admin page: manage
    the date must be in the format of yyyy-mm-dd hh:mm
"""
    def backup_csv(self):
        out = StringIO.StringIO()
        writer = csv.writer(out, lineterminator='\n')
        fields = Impact.fields().keys()
        writer.writerow(fields)
        q = Impact.all()
        for r in q:
            row = []
            for fld in fields:
                row.append(getattr(r, fld))
            writer.writerow(row)
        csvfile = CsvFile()
        csvfile.csvfile = db.Blob(out.getvalue())
        csvfile.name = 'backup'
        csvfile.put()
        
    def delete_all(self):
        '''delete all the tables'''
        db.delete(Impact.all())
        db.delete(TrackChange.all())
        
    def insert_record(self, record):
        '''insert a record'''
        
        i = TableRecord(None, Impact.fields().keys(), ['ctime', 'mtime', 'user'])
        for fld in Impact.fields().keys():
            i[fld] = record[fld]
        i.insert(Impact)
        
    def import_record(self, record):
        record = clean_record(record)
        if record.get('key'):
            #existing record, update
            self.update_record(record)
        else:
            self.insert_record(record)
            
    def update_record(self, record):
        '''update a record'''
        
        i = TableRecord(record['key'], Impact.fields().keys(), ['ctime', 'mtime', 'user'])
        for fld in Impact.fields().keys():
            i[fld] = record[fld]
        i.save_changes()
    def upload_csv(self):
        self.backup_csv()
        csvfile = CsvFile()
        csvfile.name = 'upload'
        csvfile.csvfile = db.Blob(self.request.get('upload'))
        
        csvfile.put()

        f = StringIO.StringIO(csvfile.csvfile)
        reader = csv.reader(f)
        #load the data
        h = reader.next()
        for l in reader:
            fe = dict(zip(h,l))
            self.import_record(fe)
            
            
    def upload_csv_backup(self):
        self.backup_csv()
        csvfile = CsvFile()
        csvfile.name = 'upload'
        csvfile.csvfile = db.Blob(self.request.get('upload'))
        
        csvfile.put()

        f = StringIO.StringIO(csvfile.csvfile)
        reader = csv.reader(f)

        #empty the table
        q = Impact.all()
        db.delete(q)
        
        db.delete(TrackChange.all())
        #load the data
        h = reader.next()
        for l in reader:
            fe = dict(zip(h,l))
            i = Impact()
            for k in h:
                v = fe[k]
                if k in ['roadway', 'adaparking', 'garage', 'sidewalk']:
                    v = (v=='TRUE')
                if k in ['x', 'y']:
                    v = float(v)
                if k in ['start_date', 'end_date']:
                    dp = v.split()[0]
                    m, d, y = dp.split('/')
                    v = datetime.datetime(int(y), int(m), int(d))
                setattr(i, k, v)
            i.put()

    def download_csv(self):
        """download all impact records as csv file"""

        out = StringIO.StringIO()
        writer = csv.writer(out, lineterminator='\n')
        fields = Impact.fields().keys()
        writer.writerow(['key'] + fields)
        q = Impact.all()
        for r in q:
            row = [str(r.key())]
            for fld in fields:
                v = getattr(r, fld)
                if fld in ['start_date', 'end_date']:
                    v = '%s/%s/%s' % (v.month, v.day, v.year)
                    
                row.append(v)
                logging.info(row)
            writer.writerow(row)
        self.response.headers["Content-Type"] = "text/csv"
        self.response.headers["Content-Disposition"] = "attachment;filename=download.csv"
        csv_text = out.getvalue()
        out.close()
        self.response.out.write(csv_text)
    def download_csvfile(self):
        k = self.request.get('filekey')
        if k:
            csvfile = db.get(k)
            self.response.headers["Content-Type"] = "text/csv"
            self.response.headers["Content-Disposition"] = "attachment;filename=download.csv"
            self.response.out.write(csvfile.csvfile)
            
        
    @login_required
    def get(self):
        if users.get_current_user():
            action = self.request.get('action')
            if action=='download':
                self.download_csv()
            elif action=='downloadcsv':
                self.download_csvfile()
            elif action=='delete':
                self.delete_all()
            else:
                 values = {
                   'upload_url': '/manage?action=upload',
                  'download_url': '/manage?action=download',
                  'delete_url': '/manage?action=delete'
                }

                 path = os.path.join(os.path.dirname(__file__), 'manage.htm')
                 self.response.out.write(template.render(path, values))
    def post(self):
        """Handle the upload"""
        if users.get_current_user():
            action = self.request.get('action')
            if action=='upload':
                self.upload_csv()